#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author:Summerday
import base64
import socket
import threading
import sys
import car
import numpy as np
import cv2
import time
import os
import oss2
import zipfile
import tarfile
import struct
from OSS import OssClient

# import GPS

IP = "192.168.34.58"
PORT = 3434
FORMAT = "utf-8"
SIZE = 1024
ADDR = (IP, PORT)
# CLIENT_DATA_PATH = "client_data"
count = 0

f = 200
pic_path = "img"
pic_name = "car"
# 位置初始化a
allowed_error = 0.0001
# cur_lat = 0.000000  # lat纬度
# 120.328433,30.242548
last_lat = 30.242548
last_ulat = 'N'  # ulat南北


# cur_ulat = 'N'


# Wait for incoming data from server
# .decode is used to turn the message in bytes to a string
def receive(socket, signal):
    while signal:
        try:
            data = socket.recv(SIZE)
            data = data.decode(FORMAT)
            # command
            if data == "init":
                init()
                print("init")

            elif data == "gps":
                # print("gps")
                try:
                    while True:
                        if GPS.GPS_read():
                            # 获取当前纬度
                            print("get location:" + GPS.lat)
                            print(type(GPS.lat))
                            cur_lat = float(GPS.lat)
                            cur_ulat = GPS.ulat
                            global last_lat
                            global last_ulat
                            diff = cur_lat - last_lat

                            if (diff < -0.0001 and cur_ulat == last_ulat) or cur_ulat != last_ulat:
                                # car.stop()
                                print("back")
                                car.turn()
                                break
                            else:
                                print("up")
                                car.move2()
                            last_ulat = cur_ulat
                            last_lat = cur_lat
                        # gps not found
                        else:
                            print("up---------")
                            car.move()

                except KeyboardInterrupt:
                    GPS.ser.close()
                    print("GPS serial Close!")

                #

            elif data == "go":
                print("go")
                car.go1()

            elif data == "shoot":
                print("shoot")
                camerashoot()

            elif data == "stop":
                car.stop()
                # 1、小车停止
                # 2、摄像头关闭
                print("stop")

            elif data == "tar":
                print("sock_client_image")
                # sock_client_image(socket)

            elif data == "task":
                oss_client = OssClient('LTAI5tEwwSBita9Y9GLePsMa', 'hJvKLmKaae9urXl3pjjuGjnIbviW2d',
                                       'oss-cn-chengdu.aliyuncs.com')
                oss_client.create_bucket("packetmqf3")
                task()
                oss_client.upload_directory("py")
                message = "ok mqf"
                sock.sendall(str.encode(message))

            else:
                print(data)
                continue
        except Exception as e:
            print(e)
            print("You have been disconnected from the server")
            signal = False
            break


def shoot():
    face_cascade = cv2.CascadeClassifier('face.xml')
    eye_cascade = cv2.CascadeClassifier('eye.xml')

    cap = cv2.VideoCapture(0)
    num = 0
    while num < 3000:
        num += 1
        print(num)
        if num % f == 1:
            ret, img = cap.read()
            img = cv2.flip(img, 1)
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray, 1.3, 5)

            for (x, y, w, h) in faces:
                cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
                roi_gray = gray[y:y + h, x:x + w]
                roi_color = img[y:y + h, x:x + w]
                print(int(x + w / 2), int(y + h / 2))
                eyes = eye_cascade.detectMultiScale(roi_gray)
                for (ex, ey, ew, eh) in eyes:
                    cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
            # imgR = cv2.flip(img, 1)
            # cv2.imshow('img', img)
            new_path = pic_path + "/" + pic_name + str(int(num / f)) + ".jpg"  # 定义图片的输出路径以及名字
            cv2.imwrite(new_path, img)

            if cv2.waitKey(10) & 0xFF == ord('q'):
                break

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()


def task():
    camera = cv2.VideoCapture(0)
    time.sleep(2)
    num = 0
    car.go()

    while True:
        if num < 15:
            num = num + 1
            success, frame = camera.read()  # 读取摄像头数据
            # cv2.imshow('Video Cam', frame) # 显示在窗口"Video Cam"上
            filename = str(num - 5) + ".jpg"
            if num > 5:
                cv2.imwrite("py/" + filename, frame)  # 存图像
            # upload(filename)
            car.right()
            # time.sleep(2)
        else:
            break
    camera.release()  # 断开摄像头
    cv2.destroyAllWindows()  # 释放所有窗口


def upload(filename):
    # 上传文件到OSS。
    # <yourObjectName>由包含文件后缀，不包含Bucket名称组成的Object完整路径，例如abc/efg/123.jpg。
    # <yourLocalFile>由本地文件路径加文件名包括后缀组成，例如/users/local/myfile.txt。
    bucket.put_object_from_file("test/" + filename, filename)


def init():
    # 删除所有已经拍摄的照片
    dir_path = pic_path
    # os.walk会得到dir_path下各个后代文件夹和其中的文件的三元组列表，顺序自内而外排列，
    # 如 log下有111文件夹，111下有222文件夹：[('D:\\log\\111\\222', [], ['22.py']), ('D:\\log\\111', ['222'], ['11.py']), ('D:\\log', ['111'], ['00.py'])]
    for root, dirs, files in os.walk(dir_path, topdown=False):
        # print(root) # 各级文件夹绝对路径
        # print(dirs) # root下一级文件夹名称列表，如 ['文件夹1','文件夹2']
        # print(files)  # root下文件名列表，如 ['文件1','文件2']
        # 第一步：删除文件
        for name in files:
            os.remove(os.path.join(root, name))  # 删除文件
        # 第二步：删除空文件夹
        for name in dirs:
            os.rmdir(os.path.join(root, name))  # 删除一个空目录


def do_zip_compress(dirpath):
    print("start zipping, the file path is:" + dirpath)
    output_name = dirpath + ".zip"
    parent_name = os.path.dirname(dirpath)
    # print("压缩文件夹目录：", parent_name)
    zip = zipfile.ZipFile(output_name, "w", zipfile.ZIP_DEFLATED)
    # 多层级压缩
    for root, dirs, files in os.walk(dirpath):
        for file in files:
            if str(file).startswith("~$"):
                continue
            filepath = os.path.join(root, file)
            # print("压缩文件路径：" + filepath)
            writepath = os.path.relpath(filepath, parent_name)
            zip.write(filepath, writepath)
    zip.close()
    # print(output_name) # output_name是最终压缩文件夹的路径，这将会是传入参数dirpth后面加个.zip
    return output_name


def sock_client_image(sock):
    filespath = pic_path
    filepath = "img.tar"
    while True:
        with tarfile.open(filepath, 'w') as tar:
            tar.add(filespath, arcname=os.path.basename(filespath))
        fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),
                            os.stat(filepath).st_size)
        sock.send(fhead)
        fp = open(filepath, 'rb')
        while True:
            data = fp.read(1024)
            if not data:
                print('{0} send over...'.format(filepath))
                break
            sock.send(data)
        fp.close()
        os.remove(filepath)
        break


# Attempt connection to server
try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(ADDR)
except Exception as e:
    print(str(e))
    print("Could not make a connection to the server")

    input("Press enter to quit")
    sys.exit(0)

# Create new thread to wait for data
moveReceiveThread = threading.Thread(target=receive, args=(sock, True))
moveReceiveThread.start()
#
# shootReceiveThread = threading.Thread(target=receive, args=(sock, True))
# shootReceiveThread.start()

# Send data to server
# str.encode is used to turn the string message into bytes so it can be sent across the network
while True:
    message = input()
    print(message)
    sock.sendall(str.encode(message))


def file_deal(file_path):  # 读取文件的方法
    mes = b''
    try:
        file = open(file_path, 'rb')
        mes = file.read()
    except:
        print('error {}'.format(file_path))
    else:
        file.close()
        return mes

# file_deal("img.zip")
# print(file_deal("img.zip"))
